<!DOCTYPE html><html lang="zh-CN" data-theme="light"><head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0,viewport-fit=cover"><title>Vue3 之 Composition API | 韩志成的个人空间</title><meta name="author" content="韩志成"><meta name="copyright" content="韩志成"><meta name="format-detection" content="telephone=no"><meta name="theme-color" content="#ffffff"><meta name="description" content="ref作用：一般用于定义基本数据类型数据，比如 String &#x2F; Boolean &#x2F; Number等原理：ref 的背后是使用 reactive 来实现的响应式语法：const x &#x3D; ref(100)访问：在 setup 中使用 .value 来访问 123456789101112131415161718192021&#x2F;&#x2F; Demo.vue&lt;template&amp;g">
<meta property="og:type" content="article">
<meta property="og:title" content="Vue3 之 Composition API">
<meta property="og:url" content="https://hzc-123456.gitee.io/hzcs-blog/2023/05/24/VUE3_Composition_API/index.html">
<meta property="og:site_name" content="韩志成的个人空间">
<meta property="og:description" content="ref作用：一般用于定义基本数据类型数据，比如 String &#x2F; Boolean &#x2F; Number等原理：ref 的背后是使用 reactive 来实现的响应式语法：const x &#x3D; ref(100)访问：在 setup 中使用 .value 来访问 123456789101112131415161718192021&#x2F;&#x2F; Demo.vue&lt;template&amp;g">
<meta property="og:locale" content="zh_CN">
<meta property="og:image" content="https://hzc-123456.gitee.io/hzcs-blog/img/avar.jpeg">
<meta property="article:published_time" content="2023-05-24T02:18:00.000Z">
<meta property="article:modified_time" content="2023-05-24T02:23:15.004Z">
<meta property="article:author" content="韩志成">
<meta property="article:tag" content="技术">
<meta name="twitter:card" content="summary">
<meta name="twitter:image" content="https://hzc-123456.gitee.io/hzcs-blog/img/avar.jpeg"><link rel="shortcut icon" href="/hzcs-blog/img/avar.jpeg"><link rel="canonical" href="https://hzc-123456.gitee.io/hzcs-blog/2023/05/24/VUE3_Composition_API/index.html"><link rel="preconnect" href="//cdn.jsdelivr.net"/><link rel="preconnect" href="//busuanzi.ibruce.info"/><link rel="stylesheet" href="/hzcs-blog/css/index.css"><link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fortawesome/fontawesome-free/css/all.min.css" media="print" onload="this.media='all'"><link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fancyapps/ui/dist/fancybox/fancybox.min.css" media="print" onload="this.media='all'"><script>const GLOBAL_CONFIG = {
  root: '/hzcs-blog/',
  algolia: undefined,
  localSearch: undefined,
  translate: undefined,
  noticeOutdate: undefined,
  highlight: {"plugin":"highlighjs","highlightCopy":true,"highlightLang":true,"highlightHeightLimit":false},
  copy: {
    success: '复制成功',
    error: '复制错误',
    noSupport: '浏览器不支持'
  },
  relativeDate: {
    homepage: false,
    post: false
  },
  runtime: '',
  dateSuffix: {
    just: '刚刚',
    min: '分钟前',
    hour: '小时前',
    day: '天前',
    month: '个月前'
  },
  copyright: undefined,
  lightbox: 'fancybox',
  Snackbar: undefined,
  source: {
    justifiedGallery: {
      js: 'https://cdn.jsdelivr.net/npm/flickr-justified-gallery/dist/fjGallery.min.js',
      css: 'https://cdn.jsdelivr.net/npm/flickr-justified-gallery/dist/fjGallery.min.css'
    }
  },
  isPhotoFigcaption: false,
  islazyload: false,
  isAnchor: false,
  percent: {
    toc: true,
    rightside: false,
  },
  autoDarkmode: false
}</script><script id="config-diff">var GLOBAL_CONFIG_SITE = {
  title: 'Vue3 之 Composition API',
  isPost: true,
  isHome: false,
  isHighlightShrink: false,
  isToc: true,
  postUpdate: '2023-05-24 10:23:15'
}</script><noscript><style type="text/css">
  #nav {
    opacity: 1
  }
  .justified-gallery img {
    opacity: 1
  }

  #recent-posts time,
  #post-meta time {
    display: inline !important
  }
</style></noscript><script>(win=>{
    win.saveToLocal = {
      set: function setWithExpiry(key, value, ttl) {
        if (ttl === 0) return
        const now = new Date()
        const expiryDay = ttl * 86400000
        const item = {
          value: value,
          expiry: now.getTime() + expiryDay,
        }
        localStorage.setItem(key, JSON.stringify(item))
      },

      get: function getWithExpiry(key) {
        const itemStr = localStorage.getItem(key)

        if (!itemStr) {
          return undefined
        }
        const item = JSON.parse(itemStr)
        const now = new Date()

        if (now.getTime() > item.expiry) {
          localStorage.removeItem(key)
          return undefined
        }
        return item.value
      }
    }
  
    win.getScript = url => new Promise((resolve, reject) => {
      const script = document.createElement('script')
      script.src = url
      script.async = true
      script.onerror = reject
      script.onload = script.onreadystatechange = function() {
        const loadState = this.readyState
        if (loadState && loadState !== 'loaded' && loadState !== 'complete') return
        script.onload = script.onreadystatechange = null
        resolve()
      }
      document.head.appendChild(script)
    })
  
    win.getCSS = (url,id = false) => new Promise((resolve, reject) => {
      const link = document.createElement('link')
      link.rel = 'stylesheet'
      link.href = url
      if (id) link.id = id
      link.onerror = reject
      link.onload = link.onreadystatechange = function() {
        const loadState = this.readyState
        if (loadState && loadState !== 'loaded' && loadState !== 'complete') return
        link.onload = link.onreadystatechange = null
        resolve()
      }
      document.head.appendChild(link)
    })
  
      win.activateDarkMode = function () {
        document.documentElement.setAttribute('data-theme', 'dark')
        if (document.querySelector('meta[name="theme-color"]') !== null) {
          document.querySelector('meta[name="theme-color"]').setAttribute('content', '#0d0d0d')
        }
      }
      win.activateLightMode = function () {
        document.documentElement.setAttribute('data-theme', 'light')
        if (document.querySelector('meta[name="theme-color"]') !== null) {
          document.querySelector('meta[name="theme-color"]').setAttribute('content', '#ffffff')
        }
      }
      const t = saveToLocal.get('theme')
    
          if (t === 'dark') activateDarkMode()
          else if (t === 'light') activateLightMode()
        
      const asideStatus = saveToLocal.get('aside-status')
      if (asideStatus !== undefined) {
        if (asideStatus === 'hide') {
          document.documentElement.classList.add('hide-aside')
        } else {
          document.documentElement.classList.remove('hide-aside')
        }
      }
    
    const detectApple = () => {
      if(/iPad|iPhone|iPod|Macintosh/.test(navigator.userAgent)){
        document.documentElement.classList.add('apple')
      }
    }
    detectApple()
    })(window)</script><meta name="generator" content="Hexo 6.3.0"></head><body><div id="sidebar"><div id="menu-mask"></div><div id="sidebar-menus"><div class="avatar-img is-center"><img src="/hzcs-blog/img/avar.jpeg" onerror="onerror=null;src='/img/friend_404.gif'" alt="avatar"/></div><div class="sidebar-site-data site-data is-center"><a href="/hzcs-blog/archives/"><div class="headline">文章</div><div class="length-num">4</div></a><a href="/hzcs-blog/tags/"><div class="headline">标签</div><div class="length-num">2</div></a><a href="/hzcs-blog/categories/"><div class="headline">分类</div><div class="length-num">4</div></a></div><hr/></div></div><div class="post" id="body-wrap"><header class="post-bg" id="page-header" style="background-image: url('/hzcs-blog/img/back.jpg')"><nav id="nav"><span id="blog-info"><a href="/hzcs-blog/" title="韩志成的个人空间"><span class="site-name">韩志成的个人空间</span></a></span><div id="menus"><div id="toggle-menu"><a class="site-page" href="javascript:void(0);"><i class="fas fa-bars fa-fw"></i></a></div></div></nav><div id="post-info"><h1 class="post-title">Vue3 之 Composition API</h1><div id="post-meta"><div class="meta-firstline"><span class="post-meta-date"><i class="far fa-calendar-alt fa-fw post-meta-icon"></i><span class="post-meta-label">发表于</span><time class="post-meta-date-created" datetime="2023-05-24T02:18:00.000Z" title="发表于 2023-05-24 10:18:00">2023-05-24</time><span class="post-meta-separator">|</span><i class="fas fa-history fa-fw post-meta-icon"></i><span class="post-meta-label">更新于</span><time class="post-meta-date-updated" datetime="2023-05-24T02:23:15.004Z" title="更新于 2023-05-24 10:23:15">2023-05-24</time></span><span class="post-meta-categories"><span class="post-meta-separator">|</span><i class="fas fa-inbox fa-fw post-meta-icon"></i><a class="post-meta-categories" href="/hzcs-blog/categories/vue3/">vue3</a></span></div><div class="meta-secondline"><span class="post-meta-separator">|</span><span class="post-meta-pv-cv" id="" data-flag-title="Vue3 之 Composition API"><i class="far fa-eye fa-fw post-meta-icon"></i><span class="post-meta-label">阅读量:</span><span id="busuanzi_value_page_pv"><i class="fa-solid fa-spinner fa-spin"></i></span></span></div></div></div></header><main class="layout" id="content-inner"><div id="post"><article class="post-content" id="article-container"><h3 id="ref"><a href="#ref" class="headerlink" title="ref"></a>ref</h3><p><strong>作用</strong>：一般用于定义基本数据类型数据，比如 String &#x2F; Boolean &#x2F; Number等<br><strong>原理</strong>：ref 的背后是使用 reactive 来实现的响应式<br><strong>语法</strong>：const x &#x3D; ref(100)<br><strong>访问</strong>：在 setup 中使用 .value 来访问</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br></pre></td><td class="code"><pre><span class="line">// Demo.vue</span><br><span class="line"></span><br><span class="line">&lt;template&gt;</span><br><span class="line">    &lt;h1&gt;ref的使用&lt;/h1&gt;</span><br><span class="line">    &lt;h1 v-text=&quot;num&quot;&gt;&lt;/h1&gt;</span><br><span class="line">    &lt;button @click=&quot;num++&quot;&gt;自增&lt;/button&gt;</span><br><span class="line">    &lt;button @click=&quot;add&quot;&gt;自增&lt;/button&gt;</span><br><span class="line">&lt;/template&gt;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">&lt;script setup&gt;</span><br><span class="line">import &#123;ref&#125; from &quot;vue&quot;</span><br><span class="line">// num叫一个ref变量，也叫ref对象</span><br><span class="line">let num = ref(1000);</span><br><span class="line">let add = ()=&gt;&#123;</span><br><span class="line">    num.value++</span><br><span class="line">&#125;</span><br><span class="line">&lt;/script&gt;</span><br><span class="line"></span><br><span class="line">&lt;style lang=&quot;less&quot; scoped&gt;</span><br><span class="line">&lt;/style&gt;</span><br></pre></td></tr></table></figure>



<h3 id="isRef"><a href="#isRef" class="headerlink" title="isRef"></a>isRef</h3><p><strong>作用</strong>：判断一个变量是否为一个 ref 对象。<br><strong>语法</strong>：const bol &#x3D; isRef(x)</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br></pre></td><td class="code"><pre><span class="line">// Demo.vue</span><br><span class="line"></span><br><span class="line">&lt;template&gt;</span><br><span class="line">  &lt;h1&gt;isRef的使用&lt;/h1&gt;</span><br><span class="line">  &lt;h1 v-text=&quot;num&quot;&gt;&lt;/h1&gt;</span><br><span class="line">  &lt;button @click=&quot;num++&quot;&gt;自增&lt;/button&gt;</span><br><span class="line">  &lt;button @click=&quot;add&quot;&gt;自增&lt;/button&gt;</span><br><span class="line">&lt;/template&gt;</span><br><span class="line"></span><br><span class="line">&lt;script setup&gt;</span><br><span class="line">import &#123;ref,isRef&#125; from &quot;vue&quot;</span><br><span class="line">let num = ref(1000);</span><br><span class="line">let add = ()=&gt;&#123;</span><br><span class="line">    num.value++</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">// num就是一个ref变化</span><br><span class="line">console.log(isRef(num)); // true</span><br><span class="line">console.log(isRef(110)); // false</span><br><span class="line">console.log(isRef(num.value)); // false</span><br><span class="line"></span><br><span class="line">&lt;/script&gt;</span><br><span class="line"></span><br><span class="line">&lt;style lang=&quot;less&quot; scoped&gt;</span><br><span class="line">&lt;/style&gt;</span><br></pre></td></tr></table></figure>



<h3 id="unref"><a href="#unref" class="headerlink" title="unref"></a>unref</h3><p><strong>作用</strong>：用于返回一个值，如果访问的是 ref变量，就返回其 .value值；如果不是 ref变量，就直接返回。<br><strong>语法</strong>：const x &#x3D; unref(y)</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br></pre></td><td class="code"><pre><span class="line">// Demo.vue</span><br><span class="line"></span><br><span class="line">&lt;template&gt;</span><br><span class="line">  &lt;h1&gt;unref的使用&lt;/h1&gt;</span><br><span class="line">  &lt;h1 v-text=&quot;num&quot;&gt;&lt;/h1&gt;</span><br><span class="line">  &lt;button @click=&quot;num++&quot;&gt;自增&lt;/button&gt;</span><br><span class="line">  &lt;button @click=&quot;add&quot;&gt;自增&lt;/button&gt;</span><br><span class="line">&lt;/template&gt;</span><br><span class="line"></span><br><span class="line">&lt;script setup&gt;</span><br><span class="line">import &#123;ref,isRef,unref&#125; from &quot;vue&quot;</span><br><span class="line">let num = ref(1000);</span><br><span class="line">let add = ()=&gt;&#123;</span><br><span class="line">    num.value++</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">console.log(isRef(num));</span><br><span class="line">// 如果给unref传递一个ref变量，得到这个ref的value值</span><br><span class="line">console.log(unref(num));</span><br><span class="line">// 如果给unref传递的不是一个ref变量，得到这个值的本身</span><br><span class="line">console.log(unref(num.value));</span><br><span class="line">console.log(unref(110));</span><br><span class="line"></span><br><span class="line">&lt;/script&gt;</span><br><span class="line"></span><br><span class="line">&lt;style lang=&quot;less&quot; scoped&gt;</span><br><span class="line">&lt;/style&gt;</span><br><span class="line"></span><br></pre></td></tr></table></figure>

<h3 id="customRef"><a href="#customRef" class="headerlink" title="customRef"></a>customRef</h3><p><strong>作用</strong>：自定义ref对象，把ref对象改写成get&#x2F;set，进一步可以为它们添加 track&#x2F;trigger。</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br></pre></td><td class="code"><pre><span class="line">// Demo.vue</span><br><span class="line"></span><br><span class="line">&lt;template&gt;</span><br><span class="line">  &lt;h1&gt;customRef的使用&lt;/h1&gt;</span><br><span class="line">  &lt;input type=&quot;text&quot; v-model=&quot;name&quot; /&gt;</span><br><span class="line">&lt;/template&gt;</span><br><span class="line"></span><br><span class="line">&lt;script setup&gt;</span><br><span class="line">// import &#123;ref,isRef,unref&#125; from &quot;vue&quot;</span><br><span class="line">// let name = ref(&quot;&quot;);</span><br><span class="line"></span><br><span class="line">import &#123; customRef,onRenderTracked,onRenderTriggered &#125; from &quot;vue&quot;</span><br><span class="line">let name = customRef((track,trigger)=&gt;&#123;</span><br><span class="line">    let value = &quot;&quot;;</span><br><span class="line">    return &#123;</span><br><span class="line">        get()&#123;</span><br><span class="line">            track(); // 如果有人访问name，就执行track()</span><br><span class="line">            return value</span><br><span class="line">        &#125;,</span><br><span class="line">        set(val)&#123;</span><br><span class="line">            trigger(); // 如果有人修改name，就执行trigger</span><br><span class="line">            value = val;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;)</span><br><span class="line">// 仅供在开发环境下，用于ref变量的调试</span><br><span class="line">onRenderTracked((ev) =&gt; console.log(&quot;name被访问了&quot;, ev));</span><br><span class="line">onRenderTriggered((ev) =&gt; console.log(&quot;name被修改了&quot;, ev));</span><br><span class="line">&lt;/script&gt;</span><br><span class="line"></span><br><span class="line">&lt;style lang=&quot;less&quot; scoped&gt;</span><br><span class="line">&lt;/style&gt;</span><br></pre></td></tr></table></figure>



<h3 id="toRef"><a href="#toRef" class="headerlink" title="toRef"></a>toRef</h3><p><strong>作用</strong>：把一个 reactive对象中的某个属性变成 ref 变量。<br><strong>语法</strong>：const x &#x3D; toRef(reactive(obj), ‘key’) &#x2F;&#x2F; x.value</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br></pre></td><td class="code"><pre><span class="line">// Demo.vue</span><br><span class="line"></span><br><span class="line">&lt;template&gt;</span><br><span class="line">  &lt;h1&gt;toRef的使用&lt;/h1&gt;</span><br><span class="line">  &lt;h1 v-text=&quot;user.name&quot;&gt;&lt;/h1&gt;</span><br><span class="line">&lt;/template&gt;</span><br><span class="line"></span><br><span class="line">&lt;script setup&gt;</span><br><span class="line">import &#123;ref,isRef,unref,reactive,toRef&#125; from &quot;vue&quot;</span><br><span class="line">let user = reactive(&#123;name:&quot;malu&quot;,age:18&#125;);</span><br><span class="line">setTimeout(() =&gt; &#123;</span><br><span class="line">    user.name = &quot;码路&quot;</span><br><span class="line">&#125;, 1000);</span><br><span class="line"></span><br><span class="line">// 能不能把user中的name变成ref变量呢？</span><br><span class="line">// 答：toRef</span><br><span class="line"></span><br><span class="line">console.log(user.name);</span><br><span class="line">console.log(isRef(user.name));</span><br><span class="line">console.log(&quot;-------&quot;);</span><br><span class="line">let name = toRef(user,&quot;name&quot;);</span><br><span class="line">console.log(name.value);</span><br><span class="line">console.log(isRef(name));</span><br><span class="line"></span><br><span class="line">&lt;/script&gt;</span><br><span class="line"></span><br><span class="line">&lt;style lang=&quot;less&quot; scoped&gt;</span><br><span class="line">&lt;/style&gt;</span><br></pre></td></tr></table></figure>



<h3 id="toRefs"><a href="#toRefs" class="headerlink" title="toRefs"></a>toRefs</h3><p><strong>作用</strong>：把一个reactive响应式对象变成ref变量。<br><strong>语法</strong>：const obj1 &#x3D; toRefs(reactive(obj))<br><strong>应用</strong>：在子组件中接收父组件传递过来的 props时，使用 toRefs把它变成响应式的。</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><span class="line">// Demo.vue</span><br><span class="line"></span><br><span class="line">&lt;template&gt;</span><br><span class="line">  &lt;h1&gt;toRefs的使用&lt;/h1&gt;</span><br><span class="line">  &lt;h2 v-text=&quot;name&quot;&gt;&lt;/h2&gt;</span><br><span class="line">  &lt;h2 v-text=&quot;age&quot;&gt;&lt;/h2&gt;</span><br><span class="line">&lt;/template&gt;</span><br><span class="line"></span><br><span class="line">&lt;script setup&gt;</span><br><span class="line">import &#123;ref,isRef,unref,reactive,toRefs&#125; from &quot;vue&quot;</span><br><span class="line">let user = reactive(&#123;name:&quot;malu&quot;,age:18&#125;);</span><br><span class="line">let &#123;name,age&#125; = toRefs(user);</span><br><span class="line">console.log(isRef(name));</span><br><span class="line">console.log(isRef(age));</span><br><span class="line">&lt;/script&gt;</span><br><span class="line"></span><br><span class="line">&lt;style lang=&quot;less&quot; scoped&gt;</span><br><span class="line">&lt;/style&gt;</span><br></pre></td></tr></table></figure>



<h3 id="shallowRef"><a href="#shallowRef" class="headerlink" title="shallowRef"></a>shallowRef</h3><p><strong>作用</strong>：对复杂层级的对象，只将其第一层变成 ref 响应。 (性能优化)<br><strong>语法</strong>：const x &#x3D; shallowRef({a:{b:{c:1}}, d:2}) 如此a、b、c、d变化都不会自动更新，需要借助 triggerRef 来强制更新。</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br></pre></td><td class="code"><pre><span class="line">// Demo.vue</span><br><span class="line"></span><br><span class="line">&lt;template&gt;</span><br><span class="line">  &lt;h1&gt;shallowRef的使用&lt;/h1&gt;</span><br><span class="line">  &lt;h1 v-text=&quot;info1.a.b.c&quot;&gt;&lt;/h1&gt;</span><br><span class="line">  &lt;button @click=&quot;add1&quot;&gt;自增&lt;/button&gt;</span><br><span class="line">  &lt;hr /&gt;</span><br><span class="line"></span><br><span class="line">  &lt;h1 v-text=&quot;info2.a.b.c&quot;&gt;&lt;/h1&gt;</span><br><span class="line">  &lt;button @click=&quot;add2&quot;&gt;自增&lt;/button&gt;</span><br><span class="line">&lt;/template&gt;</span><br><span class="line"></span><br><span class="line">&lt;script setup&gt;</span><br><span class="line">import &#123;shallowRef,ref,triggerRef&#125; from &quot;vue&quot;</span><br><span class="line"></span><br><span class="line">// let info1 = ref(&quot;wc&quot;);</span><br><span class="line">// ref是定义基本数据数据的响应式</span><br><span class="line">// reactive是定义引用数据类型的响应式</span><br><span class="line">// 其实ref也可以定义，如果ref中写了一人引用数据类型，它的内部还是会调用reactive</span><br><span class="line">let info1 = ref(&#123;a:&#123;b:&#123;c:3&#125;&#125;&#125;);</span><br><span class="line">console.log(info1.value.a.b.c);</span><br><span class="line">let add1 = ()=&gt;&#123;</span><br><span class="line">    info1.value.a.b.c++</span><br><span class="line">&#125;</span><br><span class="line">// -------------------</span><br><span class="line"></span><br><span class="line">// &#123;a:&#123;b:&#123;c:3&#125;&#125;&#125; 整体替换的话是响应式的，对a,b,c修改并不是响应式的</span><br><span class="line">let info2 = shallowRef(&#123;a:&#123;b:&#123;c:3&#125;&#125;&#125;);</span><br><span class="line">console.log(info2.value.a.b.c);</span><br><span class="line">let add2 = ()=&gt;&#123;</span><br><span class="line">    // info2.value = &#123;a:&#123;b:&#123;c:10000&#125;&#125;&#125;</span><br><span class="line">    // info2.value.a = &#123;b:&#123;c:10000&#125;&#125;</span><br><span class="line">    // info2.value.a.b = &#123;c:10000&#125;</span><br><span class="line">    // info2.value.a.b.c = 10000</span><br><span class="line">    info2.value.a.b.c++</span><br><span class="line"></span><br><span class="line">    triggerRef(info2); // 强制刷新页面</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">&lt;/script&gt;</span><br><span class="line">&lt;style lang=&quot;less&quot; scoped&gt;</span><br><span class="line">&lt;/style&gt;</span><br></pre></td></tr></table></figure>



<h3 id="triggerRef"><a href="#triggerRef" class="headerlink" title="triggerRef"></a>triggerRef</h3><p><strong>作用</strong>：强制更新一个 shallowRef对象的渲染。<br><strong>语法</strong>：triggerRef(shallowRef对象)</p>
<p>参考上例</p>
<h3 id="reactive"><a href="#reactive" class="headerlink" title="reactive"></a>reactive</h3><p><strong>作用</strong>：定义响应式变量，一般用于定义引用数据类型。如果是基本数据类型，建议使用ref来定义。<br><strong>语法</strong>：const info &#x3D; reactive([] | {})</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br></pre></td><td class="code"><pre><span class="line">// Demo.vue</span><br><span class="line"></span><br><span class="line">&lt;template&gt;</span><br><span class="line">  &lt;h1&gt;reactive的使用&lt;/h1&gt;</span><br><span class="line">  &lt;h1 v-text=&quot;user.a&quot;&gt;&lt;/h1&gt;</span><br><span class="line">  &lt;button @click=&quot;add&quot;&gt;+1&lt;/button&gt;</span><br><span class="line">  &lt;h1 v-text=&quot;user.b&quot;&gt;&lt;/h1&gt;</span><br><span class="line">&lt;/template&gt;</span><br><span class="line"></span><br><span class="line">&lt;script setup&gt;</span><br><span class="line">import &#123;reactive&#125; from &quot;vue&quot;</span><br><span class="line">let obj = &#123;a:1,b:2,c:3&#125;</span><br><span class="line">let user = reactive(obj);</span><br><span class="line"></span><br><span class="line">let add = ()=&gt;&#123;</span><br><span class="line">    user.a++</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">&lt;/script&gt;</span><br><span class="line">&lt;style lang=&quot;less&quot; scoped&gt;</span><br><span class="line">&lt;/style&gt;</span><br></pre></td></tr></table></figure>



<h3 id="readonly"><a href="#readonly" class="headerlink" title="readonly"></a>readonly</h3><p><strong>作用</strong>：把一个对象，变成只读的。<br><strong>语法</strong>：const rs &#x3D; readonly(ref对象 | reactive对象 | 普通对象)</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br></pre></td><td class="code"><pre><span class="line">// Demo.vue</span><br><span class="line"></span><br><span class="line">&lt;template&gt;</span><br><span class="line">  &lt;h1&gt;readonly的使用&lt;/h1&gt;</span><br><span class="line">  &lt;h1 v-text=&quot;user2.a&quot;&gt;&lt;/h1&gt;</span><br><span class="line">  &lt;button @click=&quot;add&quot;&gt;+1&lt;/button&gt;</span><br><span class="line">&lt;/template&gt;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">&lt;script setup&gt;</span><br><span class="line">import &#123;reactive,readonly,isReadonly,ref&#125; from &quot;vue&quot;</span><br><span class="line">let obj = &#123;a:1,b:2&#125;</span><br><span class="line">let user = reactive(obj);</span><br><span class="line"></span><br><span class="line">// readonly(ref对象 | reactive对象 | 普通对象)</span><br><span class="line">// readonly它内部是拦截的set</span><br><span class="line">let info = readonly(&#123;c:3,d:4&#125;); // info叫readonly对象</span><br><span class="line">let user2 = readonly(user)</span><br><span class="line">let foo = ref(100);</span><br><span class="line">let foo2 = readonly(foo)</span><br><span class="line">let xx = 666;</span><br><span class="line"></span><br><span class="line">let add = ()=&gt;&#123;</span><br><span class="line">    // key &quot;a&quot; failed: target is readonly. </span><br><span class="line">    // a是只读，只能使用，不能修改</span><br><span class="line">    user2.a++; // 不能</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">console.log(isReadonly(info)); // true</span><br><span class="line">console.log(isReadonly(user2)); // true</span><br><span class="line">console.log(isReadonly(foo2)); // true</span><br><span class="line">console.log(&quot;---------&quot;);</span><br><span class="line">console.log(isReadonly(foo));</span><br><span class="line">console.log(isReadonly(user));</span><br><span class="line">console.log(isReadonly(xx));</span><br><span class="line">&lt;/script&gt;</span><br><span class="line">&lt;style lang=&quot;less&quot; scoped&gt;</span><br><span class="line">&lt;/style&gt;</span><br></pre></td></tr></table></figure>



<h3 id="isReadonly"><a href="#isReadonly" class="headerlink" title="isReadonly"></a>isReadonly</h3><p><strong>作用</strong>: 判断一个变量是不是只读的。<br><strong>语法</strong>：const bol &#x3D; isReadonly(变量)</p>
<p>参考上例</p>
<h3 id="isReactive"><a href="#isReactive" class="headerlink" title="isReactive"></a>isReactive</h3><p><strong>作用</strong>：判断一变量是不是 reactive的。<br><strong>注意</strong>：被 readonly代理过的 reactive变量，调用 isReactive 也是返回 true的。</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br></pre></td><td class="code"><pre><span class="line">// Demo.vue</span><br><span class="line"></span><br><span class="line">&lt;template&gt;</span><br><span class="line">  &lt;h1&gt;isReactive的使用&lt;/h1&gt;</span><br><span class="line">  &lt;h1 v-text=&quot;user2.a&quot;&gt;&lt;/h1&gt;</span><br><span class="line">  &lt;button @click=&quot;add&quot;&gt;+1&lt;/button&gt;</span><br><span class="line">&lt;/template&gt;</span><br><span class="line"></span><br><span class="line">&lt;script setup&gt;</span><br><span class="line">import &#123; reactive, readonly, ref, isReactive &#125; from &quot;vue&quot;;</span><br><span class="line"></span><br><span class="line">const uu = &#123; a: 1, b: 2 &#125;;</span><br><span class="line">const user = reactive(uu);</span><br><span class="line"></span><br><span class="line">const info = readonly(&#123; c: 3, d: 4 &#125;); // 是Readonly</span><br><span class="line">const user2 = readonly(user); // 是Readonly</span><br><span class="line">const foo = ref(100);  // foo是一个ref，不是reactive</span><br><span class="line">const foo2 = readonly(foo); // 是Readonly</span><br><span class="line"></span><br><span class="line">const xx = 100;</span><br><span class="line"></span><br><span class="line">const add = () =&gt; &#123;</span><br><span class="line">  user2.a++;</span><br><span class="line">&#125;;</span><br><span class="line">// 如果readonly包了一个reactive，这个readonly也是reactive</span><br><span class="line">// 如果readonly包了一个ref，这个readonly不是reactive</span><br><span class="line">console.log(isReactive(user2));</span><br><span class="line">console.log(isReactive(user));</span><br><span class="line">console.log(isReactive(foo2));</span><br><span class="line">console.log(isReactive(foo));</span><br><span class="line">console.log(isReactive(info));</span><br><span class="line">console.log(isReactive(xx));</span><br><span class="line"></span><br><span class="line">&lt;/script&gt;</span><br><span class="line">&lt;style lang=&quot;less&quot; scoped&gt;</span><br><span class="line">&lt;/style&gt;</span><br></pre></td></tr></table></figure>



<h3 id="isProxy"><a href="#isProxy" class="headerlink" title="isProxy"></a>isProxy</h3><p><strong>作用</strong>：判断一个变量是不是 readonly 或 reactive的。</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br></pre></td><td class="code"><pre><span class="line">// Demo.vue</span><br><span class="line"></span><br><span class="line">&lt;template&gt;</span><br><span class="line">  &lt;h1&gt;isProxy的使用&lt;/h1&gt;</span><br><span class="line">  &lt;h1 v-text=&quot;user2.a&quot;&gt;&lt;/h1&gt;</span><br><span class="line">  &lt;button @click=&quot;add&quot;&gt;+1&lt;/button&gt;</span><br><span class="line">&lt;/template&gt;</span><br><span class="line"></span><br><span class="line">&lt;script setup&gt;</span><br><span class="line">import &#123; reactive, readonly, ref, isReactive,isProxy &#125; from &quot;vue&quot;;</span><br><span class="line"></span><br><span class="line">const uu = &#123; a: 1, b: 2 &#125;;</span><br><span class="line">const user = reactive(uu);</span><br><span class="line"></span><br><span class="line">const info = readonly(&#123; c: 3, d: 4 &#125;); // 是Readonly</span><br><span class="line">const user2 = readonly(user); // 是Readonly</span><br><span class="line">const foo = ref(100);  // foo是一个ref，不是reactive</span><br><span class="line">const foo2 = readonly(foo); // 是Readonly</span><br><span class="line"></span><br><span class="line">const xx = 100;</span><br><span class="line"></span><br><span class="line">const add = () =&gt; &#123;</span><br><span class="line">  user2.a++;</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line">// isProxy判断一个变量是否是readonly或reactive</span><br><span class="line">console.log(isProxy(uu));</span><br><span class="line">console.log(isProxy(user));</span><br><span class="line">console.log(isProxy(info));</span><br><span class="line">console.log(isProxy(user2));</span><br><span class="line">console.log(isProxy(foo));</span><br><span class="line">console.log(isProxy(foo2));</span><br><span class="line">console.log(isProxy(xx));</span><br><span class="line"></span><br><span class="line">&lt;/script&gt;</span><br><span class="line">&lt;style lang=&quot;less&quot; scoped&gt;</span><br><span class="line">&lt;/style&gt;</span><br></pre></td></tr></table></figure>



<h3 id="toRaw"><a href="#toRaw" class="headerlink" title="toRaw"></a>toRaw</h3><p><strong>作用</strong>：得到返回 reactive变量或 readonly变量的”原始对象”。<br><strong>语法</strong>:：const raw &#x3D; toRaw(reactive变量或readonly变量)<br><strong>说明</strong>：reactive(obj)、readonly(obj) 和 obj 之间是一种代理关系，并且它们之间是一种浅拷贝的关系。obj 变化，会导致reactive(obj) 同步变化，反之一样。</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br></pre></td><td class="code"><pre><span class="line">// Demo.vue</span><br><span class="line"></span><br><span class="line">&lt;template&gt;</span><br><span class="line">  &lt;h1&gt;toRaw的使用&lt;/h1&gt;</span><br><span class="line">&lt;/template&gt;</span><br><span class="line"></span><br><span class="line">&lt;script setup&gt;</span><br><span class="line">import &#123; reactive, toRaw, readonly &#125; from &quot;vue&quot;;</span><br><span class="line"></span><br><span class="line">const uu = &#123; a: 1, b: 2 &#125;;  // 原始对象</span><br><span class="line">const user = reactive(uu);  // 把uu变成了reactive</span><br><span class="line"></span><br><span class="line">const info = readonly(user);  // 把reactive变成readonly</span><br><span class="line"></span><br><span class="line">// toRaw(user) 把一个reactive打回原形  变成原始对象</span><br><span class="line">// 它们之间的转化是浅copy</span><br><span class="line">// toRaw(user)  和  uu 始终是同一个对象</span><br><span class="line">console.log(toRaw(user) === uu);  // true</span><br><span class="line">// reactive对象和原始对象比较：false</span><br><span class="line">console.log(user === uu);</span><br><span class="line"></span><br><span class="line">console.log(&quot;-----------&quot;);</span><br><span class="line"></span><br><span class="line">// toRaw(info) 把一个readmonly打回原形 还是得原始对象</span><br><span class="line">console.log(toRaw(info) === uu);</span><br><span class="line">&lt;/script&gt;</span><br></pre></td></tr></table></figure>



<h3 id="markRaw"><a href="#markRaw" class="headerlink" title="markRaw"></a>markRaw</h3><p><strong>作用</strong>：把一个普通对象标记成”永久原始”，从此将无法再变成proxy了。<br><strong>语法</strong>：const raw &#x3D; markRaw({a, b})</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br></pre></td><td class="code"><pre><span class="line">// Demo.vue</span><br><span class="line"></span><br><span class="line">&lt;template&gt;</span><br><span class="line">  &lt;h1&gt;markRaw的使用&lt;/h1&gt;</span><br><span class="line">  &lt;h2&gt;&#123;&#123; yy2.a &#125;&#125;&lt;/h2&gt;</span><br><span class="line">  &lt;button @click=&quot;add&quot;&gt;+1&lt;/button&gt;</span><br><span class="line">&lt;/template&gt;</span><br><span class="line"></span><br><span class="line">&lt;script setup&gt;</span><br><span class="line">import &#123; reactive, markRaw, isReactive &#125; from &quot;vue&quot;;</span><br><span class="line"></span><br><span class="line">// &#123; a: 1, b: 2 &#125; 就是原始对象</span><br><span class="line">// markRaw(&#123; a: 1, b: 2 &#125;) 把原始对象标记为不可代理</span><br><span class="line">// 不能是raactive或readonly</span><br><span class="line">const user = markRaw(&#123; a: 1, b: 2 &#125;);</span><br><span class="line"></span><br><span class="line">// yy2不是reactive  因为user被标记为永久原始</span><br><span class="line">const yy2 = reactive(user);</span><br><span class="line">console.log(isReactive(yy2));</span><br><span class="line"></span><br><span class="line">// 不是一个reactive，不是响应式的</span><br><span class="line">const add = () =&gt; &#123;</span><br><span class="line">  yy2.a++;</span><br><span class="line">&#125;;</span><br><span class="line">&lt;/script&gt;</span><br></pre></td></tr></table></figure>



<h3 id="shallowReactive"><a href="#shallowReactive" class="headerlink" title="shallowReactive"></a>shallowReactive</h3><p><strong>作用</strong>：定义一个reactive变量，只对它的第一层进行Proxy, 所以只有第一层变化时视图才更新。<br><strong>语法</strong>：const obj &#x3D; shallowReactive({a:{b:9}})</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br></pre></td><td class="code"><pre><span class="line">// Demo.vue</span><br><span class="line"></span><br><span class="line">&lt;template&gt;</span><br><span class="line">  &lt;h1&gt;shallowReactive的使用&lt;/h1&gt;</span><br><span class="line">  &lt;h2&gt;&#123;&#123; aa &#125;&#125;&lt;/h2&gt;</span><br><span class="line">  &lt;button @click=&quot;change&quot;&gt;change&lt;/button&gt;</span><br><span class="line">&lt;/template&gt;</span><br><span class="line"></span><br><span class="line">&lt;script setup&gt;</span><br><span class="line">import &#123; shallowReactive &#125; from &quot;vue&quot;;</span><br><span class="line"></span><br><span class="line">// &#123; a: &#123; b: &#123; c: 1 &#125; &#125; &#125;   利用shallowReactive，只能对第1层代理</span><br><span class="line">// 所谓的第1层就是a这个属性</span><br><span class="line">let aa = shallowReactive(&#123; a: &#123; b: &#123; c: 1 &#125; &#125; &#125;);</span><br><span class="line">const change = () =&gt; &#123;</span><br><span class="line">    // aa = &#123;d:&#123;e:&#123;f:1000&#125;&#125;&#125;</span><br><span class="line">    // aa.a = &#123; b: &#123; c: 2 &#125; &#125;;</span><br><span class="line">    // aa.a.b = &#123;c:110&#125;</span><br><span class="line">    // aa.a.b.c = 110</span><br><span class="line">    aa.a.b.c++</span><br><span class="line">&#125;;</span><br><span class="line">&lt;/script&gt;</span><br></pre></td></tr></table></figure>

<h3 id="shallowReadonly"><a href="#shallowReadonly" class="headerlink" title="shallowReadonly"></a>shallowReadonly</h3><p><strong>作用</strong>：定义一个reactive变量，只有第一层是只读的。<br><strong>语法</strong>：const obj &#x3D; shallowReadonly({a:{b:9}})</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br></pre></td><td class="code"><pre><span class="line">// Demo.vue</span><br><span class="line"></span><br><span class="line">&lt;template&gt;</span><br><span class="line">  &lt;h1&gt;shallowReadonly的使用&lt;/h1&gt;</span><br><span class="line">  &lt;h2&gt;&#123;&#123; mm &#125;&#125;&lt;/h2&gt;</span><br><span class="line">  &lt;button @click=&quot;change&quot;&gt;change&lt;/button&gt;</span><br><span class="line">&lt;/template&gt;</span><br><span class="line"></span><br><span class="line">&lt;script setup&gt;</span><br><span class="line">import &#123; shallowReadonly, reactive &#125; from &quot;vue&quot;;</span><br><span class="line"></span><br><span class="line">// shallowReadonly只有第1层是只读的</span><br><span class="line">// 第一层：a  d</span><br><span class="line">// 第二层：b</span><br><span class="line">// 第三层：c</span><br><span class="line">const mm = shallowReadonly(reactive(&#123; a: &#123; b: &#123; c: 1 &#125; &#125;, d: 2 &#125;));</span><br><span class="line">const change = () =&gt; &#123;</span><br><span class="line">    // mm.d++  // 不能改</span><br><span class="line">    mm.a.b.c++; // 可以改</span><br><span class="line">&#125;;</span><br><span class="line">&lt;/script&gt;</span><br></pre></td></tr></table></figure>

<h3 id="computed"><a href="#computed" class="headerlink" title="computed"></a>computed</h3><p><strong>作用</strong>：对响应式变量进行缓存计算。<br><strong>语法</strong>：const c &#x3D; computed(fn &#x2F; {get, set})</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br></pre></td><td class="code"><pre><span class="line">// Demo.vue</span><br><span class="line"></span><br><span class="line">&lt;template&gt;</span><br><span class="line">  &lt;h1&gt;computed的使用&lt;/h1&gt;</span><br><span class="line">  &lt;h1 v-text=&quot;num&quot;&gt;&lt;/h1&gt;</span><br><span class="line">  &lt;button @click=&quot;num++&quot;&gt;自增&lt;/button&gt;</span><br><span class="line">  &lt;h2&gt;&#123;&#123; total &#125;&#125;&lt;/h2&gt;</span><br><span class="line">  &lt;input type=&quot;text&quot; v-model.number=&quot;total&quot; /&gt;</span><br><span class="line">&lt;/template&gt;</span><br><span class="line"></span><br><span class="line">&lt;script setup&gt;</span><br><span class="line">import &#123; ref, computed &#125; from &quot;vue&quot;;</span><br><span class="line">let num = ref(100)</span><br><span class="line"></span><br><span class="line">// let total = computed(&#123;</span><br><span class="line">//   get() &#123;</span><br><span class="line">//     return num.value * 100</span><br><span class="line">//   &#125;,</span><br><span class="line">//   set(val) &#123;</span><br><span class="line">//     num.value = val / 100</span><br><span class="line">//   &#125;</span><br><span class="line">// &#125;)</span><br><span class="line"></span><br><span class="line">let total = computed(() =&gt; &#123;</span><br><span class="line">  return 666</span><br><span class="line">&#125;)</span><br><span class="line">&lt;/script&gt;</span><br></pre></td></tr></table></figure>

<h3 id="watch"><a href="#watch" class="headerlink" title="watch"></a>watch</h3><p><strong>作用</strong>：用于监听响应式变量的变化，组件初始化时，它不执行。<br><strong>语法</strong>：const stop &#x3D; watch(x, (new, old)&#x3D;&gt;{})，调用stop() 可以停止监听。<br><strong>语法</strong>：const stop &#x3D; watch([x, y], ([newX, newY], [oldX, oldY])&#x3D;&gt;{})，调用stop()可以停止监听。</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br></pre></td><td class="code"><pre><span class="line">// Demo.vue</span><br><span class="line"></span><br><span class="line">&lt;template&gt;</span><br><span class="line">  &lt;h1&gt;watch的使用&lt;/h1&gt;</span><br><span class="line">  &lt;h1 v-text=&quot;num&quot;&gt;&lt;/h1&gt;</span><br><span class="line">  &lt;button @click=&quot;num++&quot;&gt;自增&lt;/button&gt;</span><br><span class="line">  &lt;h2&gt;&#123;&#123; total &#125;&#125;&lt;/h2&gt;</span><br><span class="line">  &lt;input type=&quot;text&quot; v-model.number=&quot;total&quot; /&gt;</span><br><span class="line">  &lt;button @click=&quot;stopAll&quot;&gt;停止一切监听&lt;/button&gt;</span><br><span class="line">&lt;/template&gt;</span><br><span class="line"></span><br><span class="line">&lt;script setup&gt;</span><br><span class="line">import &#123; ref, computed, watch &#125; from &quot;vue&quot;;</span><br><span class="line">let num = ref(100)</span><br><span class="line">const total = computed(&#123;</span><br><span class="line">  get() &#123;</span><br><span class="line">    return num.value * 100;</span><br><span class="line">  &#125;,</span><br><span class="line">  set(val) &#123;</span><br><span class="line">    num.value = val / 100;</span><br><span class="line">  &#125;,</span><br><span class="line">&#125;);</span><br><span class="line"></span><br><span class="line">// ------------------------------------</span><br><span class="line">let stop1 = watch(num, (newNum, oldNum) =&gt; &#123;</span><br><span class="line">  console.log(&quot;num变化了：&quot;, newNum, oldNum);</span><br><span class="line">&#125;)</span><br><span class="line"></span><br><span class="line">// ------------------------------------</span><br><span class="line">let stop2 = watch([num, total], ([newNum, newTotal], [oldNum, oldTotal]) =&gt; &#123;</span><br><span class="line">  console.log(&quot;num变化了：&quot;, newNum, oldNum);</span><br><span class="line">  console.log(&quot;total变化了：&quot;, newTotal, oldTotal);</span><br><span class="line">&#125;)</span><br><span class="line">// ------------------------------------</span><br><span class="line">let stopAll = () =&gt; &#123;</span><br><span class="line">  stop1();</span><br><span class="line">  stop2();</span><br><span class="line">&#125;</span><br><span class="line">&lt;/script&gt;</span><br></pre></td></tr></table></figure>

<h3 id="watchEffect"><a href="#watchEffect" class="headerlink" title="watchEffect"></a>watchEffect</h3><p><strong>作用</strong>：相当于是 react中的 useEffect()，用于执行各种副作用。<br><strong>语法</strong>：</p>
<ul>
<li>const stop &#x3D; watchEffect(fn)，默认其 flush:’pre’，前置执行的副作用。</li>
<li>watchPostEffect，等价于 watchEffect(fn, {flush:’post’})，后置执行的副作用。</li>
<li>watchSyncEffect，等价于 watchEffect(fn, {flush:’sync’})，同步执行的副作用。</li>
<li>特点：watchEffect 会自动收集其内部响应式依赖，当响应式依赖发变化时，这个watchEffect将再次执行，直到你手动 stop() 掉它。</li>
</ul>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br></pre></td><td class="code"><pre><span class="line">// Demo.vue</span><br><span class="line"></span><br><span class="line">&lt;template&gt;</span><br><span class="line">  &lt;h1&gt;watchEffect的使用&lt;/h1&gt;</span><br><span class="line">  &lt;h1 v-text=&quot;num&quot;&gt;&lt;/h1&gt;</span><br><span class="line">  &lt;button @click=&quot;num++&quot;&gt;自增&lt;/button&gt;</span><br><span class="line">  &lt;hr /&gt;</span><br><span class="line">  &lt;h1 v-text=&quot;foo&quot;&gt;&lt;/h1&gt;</span><br><span class="line">  &lt;button @click=&quot;foo--&quot;&gt;自减&lt;/button&gt;</span><br><span class="line">  &lt;hr /&gt;</span><br><span class="line">  &lt;h1 v-text=&quot;bar.a&quot;&gt;&lt;/h1&gt;</span><br><span class="line">  &lt;button @click=&quot;bar.a++&quot;&gt;改变&lt;/button&gt;</span><br><span class="line">&lt;/template&gt;</span><br><span class="line"></span><br><span class="line">&lt;script setup&gt;</span><br><span class="line">import &#123; ref, computed, watchEffect, watchPostEffect, reactive &#125; from &quot;vue&quot;;</span><br><span class="line">let num = ref(1)</span><br><span class="line">let foo = ref(200)</span><br><span class="line">let bar = reactive(&#123; a: 1, b: 2 &#125;)</span><br><span class="line"></span><br><span class="line">// watchEffect 处理各种副作用  类似于生命周期函数</span><br><span class="line">// 下面的代码，一开始只会执行一次，后面不会执行</span><br><span class="line">// watchEffect(() =&gt; &#123;</span><br><span class="line">//   console.log(&quot;执行副作用1&quot;);</span><br><span class="line">// &#125;)</span><br><span class="line"></span><br><span class="line">// 当num数据发生了变化，需要重新执行，你需要在下面的代码使用num</span><br><span class="line">// watchEffect依赖了num数据，num数据变化，就会重新执行</span><br><span class="line">// watchEffect(() =&gt; &#123;</span><br><span class="line">//   console.log(&quot;执行副作用1&quot;,num.value);</span><br><span class="line">// &#125;)</span><br><span class="line"></span><br><span class="line">// 只能foo数据变化，才会重新执行</span><br><span class="line">// watchEffect(() =&gt; &#123;</span><br><span class="line">//   console.log(&quot;执行副作用1&quot;, foo.value);</span><br><span class="line">// &#125;)</span><br><span class="line"></span><br><span class="line">// watchEffect(() =&gt; &#123;</span><br><span class="line">//   console.log(&quot;执行副作用1&quot;, foo.value,num.value);</span><br><span class="line">// &#125;)</span><br><span class="line"></span><br><span class="line">// --------------------------------------------</span><br><span class="line"></span><br><span class="line">// watchEffect(() =&gt; &#123;  // pre先执行</span><br><span class="line">//   console.log(&quot;执行副作用1&quot;, foo.value, num.value);</span><br><span class="line">// &#125;, &#123; flush: &quot;pre&quot; &#125;)</span><br><span class="line"></span><br><span class="line">// watchEffect(() =&gt; &#123;  // post表示后执行</span><br><span class="line">//   console.log(&quot;执行副作用2&quot;, foo.value, num.value);</span><br><span class="line">// &#125;, &#123; flush: &quot;post&quot; &#125;)</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">// --------------------------------------------</span><br><span class="line"></span><br><span class="line">// // 这样写等价与  &#123; flush: &quot;pre&quot; &#125;)</span><br><span class="line">// watchEffect(() =&gt; &#123;  // pre先执行</span><br><span class="line">//   console.log(&quot;执行副作用1&quot;, foo.value, num.value);</span><br><span class="line">// &#125;)</span><br><span class="line"></span><br><span class="line">// // 这样写等价与  &#123; flush: &quot;post&quot; &#125;)</span><br><span class="line">// watchPostEffect(() =&gt; &#123;  // post表示后执行</span><br><span class="line">//   console.log(&quot;执行副作用2&quot;, foo.value, num.value);</span><br><span class="line">// &#125;)</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">// --------------------------------------------</span><br><span class="line"></span><br><span class="line">// 1  3  2</span><br><span class="line">// watchEffect(() =&gt; &#123;  // pre先执行</span><br><span class="line">//   console.log(&quot;执行副作用1&quot;, foo.value, num.value);</span><br><span class="line">// &#125;, &#123; flush: &quot;pre&quot; &#125;)</span><br><span class="line"></span><br><span class="line">// watchEffect(() =&gt; &#123;  // post表示后执行</span><br><span class="line">//   console.log(&quot;执行副作用2&quot;, foo.value, num.value);</span><br><span class="line">// &#125;, &#123; flush: &quot;post&quot; &#125;)</span><br><span class="line"></span><br><span class="line">// // sync 同步执行，轮到它的时候就执行</span><br><span class="line">// watchEffect(() =&gt; &#123;  // post表示后执行</span><br><span class="line">//   console.log(&quot;执行副作用3&quot;, foo.value, num.value);</span><br><span class="line">// &#125;, &#123; flush: &quot;sync&quot; &#125;);</span><br><span class="line"></span><br><span class="line">// --------------------------------------------</span><br><span class="line"></span><br><span class="line">//  3  1  2</span><br><span class="line"></span><br><span class="line">// sync 同步执行，轮到它的时候就执行</span><br><span class="line">// 等价于：watchSyncEffect</span><br><span class="line">watchEffect(() =&gt; &#123;  // post表示后执行</span><br><span class="line">  console.log(&quot;执行副作用3&quot;, foo.value, num.value);</span><br><span class="line">&#125;, &#123; flush: &quot;sync&quot; &#125;);</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">watchEffect(() =&gt; &#123;  // pre先执行</span><br><span class="line">  console.log(&quot;执行副作用1&quot;, foo.value, num.value);</span><br><span class="line">&#125;, &#123; flush: &quot;pre&quot; &#125;)</span><br><span class="line"></span><br><span class="line">watchEffect(() =&gt; &#123;  // post表示后执行</span><br><span class="line">  console.log(&quot;执行副作用2&quot;, foo.value, num.value);</span><br><span class="line">&#125;, &#123; flush: &quot;post&quot; &#125;)</span><br><span class="line">&lt;/script&gt;</span><br></pre></td></tr></table></figure>

<h3 id="生命周期钩子"><a href="#生命周期钩子" class="headerlink" title="生命周期钩子"></a>生命周期钩子</h3><ul>
<li>选项式的 beforeCreate、created，被setup替代了。setup表示组件被创建之前、props被解析之后执行，它是组合式 API 的入口。</li>
<li>选项式的 beforeDestroy、destroyed 被更名为 beforeUnmount、unmounted。</li>
<li>新增了两个选项式的生命周期 renderTracked、renderTriggered，它们只在开发环境有用，常用于调试。</li>
<li>在使用 setup组合时，不建议使用选项式的生命周期，建议使用 on* 系列 hooks生命周期。</li>
</ul>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br></pre></td><td class="code"><pre><span class="line">// Demo.vue</span><br><span class="line"></span><br><span class="line">&lt;template&gt;</span><br><span class="line">  &lt;h1 v-text=&quot;num&quot;&gt;&lt;/h1&gt;</span><br><span class="line">  &lt;button @click=&quot;num++&quot;&gt;自增&lt;/button&gt;</span><br><span class="line">&lt;/template&gt;</span><br><span class="line"></span><br><span class="line">&lt;script setup&gt;</span><br><span class="line">import &#123;</span><br><span class="line">  ref,</span><br><span class="line">  onBeforeMount,</span><br><span class="line">  onMounted,</span><br><span class="line">  onBeforeUpdate,</span><br><span class="line">  onUpdated,</span><br><span class="line">  onBeforeUnmount,</span><br><span class="line">  onUnmounted,</span><br><span class="line">  onRenderTracked,</span><br><span class="line">  onRenderTriggered,</span><br><span class="line">  onActivated,</span><br><span class="line">  onDeactivated,</span><br><span class="line">  onErrorCaptured,</span><br><span class="line">&#125; from &quot;vue&quot;;</span><br><span class="line"></span><br><span class="line">console.log(&quot;---setup&quot;);</span><br><span class="line">const num = ref(100);</span><br><span class="line">// 挂载阶段</span><br><span class="line">onBeforeMount(() =&gt; console.log(&quot;---开始挂载&quot;));</span><br><span class="line">onRenderTracked(() =&gt; console.log(&quot;---跟踪&quot;));</span><br><span class="line">onMounted(() =&gt; console.log(&quot;---挂载完成&quot;));</span><br><span class="line"></span><br><span class="line">// 更新阶段</span><br><span class="line">onRenderTriggered(() =&gt; console.log(&quot;---触发&quot;));</span><br><span class="line">onBeforeUpdate(() =&gt; console.log(&quot;---开始更新&quot;));</span><br><span class="line">onUpdated(() =&gt; console.log(&quot;---更新完成&quot;));</span><br><span class="line"></span><br><span class="line">// 销毁阶段</span><br><span class="line">onBeforeUnmount(() =&gt; console.log(&quot;---开始销毁&quot;));</span><br><span class="line">onUnmounted(() =&gt; console.log(&quot;---销毁完成&quot;));</span><br><span class="line"></span><br><span class="line">// 与动态组件有关</span><br><span class="line">onActivated(() =&gt; console.log(&quot;---激活&quot;));</span><br><span class="line">onDeactivated(() =&gt; console.log(&quot;---休眠&quot;));</span><br><span class="line"></span><br><span class="line">// 异常捕获</span><br><span class="line">onErrorCaptured(() =&gt; console.log(&quot;---错误捕获&quot;));</span><br><span class="line">&lt;/script&gt;</span><br></pre></td></tr></table></figure>

<h3 id="provide-x2F-inject"><a href="#provide-x2F-inject" class="headerlink" title="provide &#x2F; inject"></a>provide &#x2F; inject</h3><p><strong>作用</strong>：在组件树中自上而下地传递数据.<br><strong>语法</strong>：provide(‘key’, value)<br><strong>语法</strong>：const value &#x3D; inject(‘key’, ‘默认值’)</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line">// App.vue</span><br><span class="line"></span><br><span class="line">&lt;template&gt;&lt;Demo /&gt;&lt;/template&gt;</span><br><span class="line"></span><br><span class="line">&lt;script setup&gt;</span><br><span class="line">import Demo from &quot;./components/Demo.vue&quot;;</span><br><span class="line"></span><br><span class="line">import &#123; ref, provide &#125; from &quot;vue&quot;;</span><br><span class="line">const msg = ref(&quot;Hello World&quot;);</span><br><span class="line">// 向组件树中注入数据</span><br><span class="line">provide(&quot;msg&quot;, msg);</span><br><span class="line">&lt;/script&gt;</span><br></pre></td></tr></table></figure>

<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line">// Demo.vue</span><br><span class="line"></span><br><span class="line">&lt;template&gt;</span><br><span class="line">  &lt;h1&gt;provide / inject的使用&lt;/h1&gt;</span><br><span class="line">  &lt;h1 v-text=&quot;msg&quot;&gt;&lt;/h1&gt;</span><br><span class="line">&lt;/template&gt;</span><br><span class="line">&lt;script setup&gt;</span><br><span class="line">import &#123; inject &#125; from &quot;vue&quot;;</span><br><span class="line">// 消费组件树中的数据，第二参数为默认值</span><br><span class="line">// inject表示注入，消费者</span><br><span class="line">// &quot;Hello Vue&quot; 是默认值</span><br><span class="line">const msg = inject(&quot;msg&quot;, &quot;Hello Vue&quot;);</span><br><span class="line">&lt;/script&gt;</span><br></pre></td></tr></table></figure>

<h3 id="getCurrentInstance"><a href="#getCurrentInstance" class="headerlink" title="getCurrentInstance"></a>getCurrentInstance</h3><p><strong>作用</strong>：用于访问内部组件实例。请不要把它当作在组合式 API 中获取 this 的替代方案来使用。<br><strong>语法</strong>：const app &#x3D; getCurrentInstance()<br><strong>场景</strong>：常用于访问 app.config.globalProperties 上的全局数据。</p>
<figure class="highlight ts"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// main.ts</span></span><br><span class="line"><span class="keyword">import</span> &#123; createApp &#125; <span class="keyword">from</span> <span class="string">&#x27;vue&#x27;</span></span><br><span class="line"><span class="keyword">import</span> <span class="string">&#x27;./style.css&#x27;</span></span><br><span class="line"><span class="keyword">import</span> <span class="title class_">App</span> <span class="keyword">from</span> <span class="string">&#x27;./App.vue&#x27;</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">let</span> app = <span class="title function_">createApp</span>(<span class="title class_">App</span>)</span><br><span class="line"><span class="comment">// Vue2.x</span></span><br><span class="line"><span class="comment">// Vue.prototype.$http = () =&gt; &#123; &#125;</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// Vue3.x</span></span><br><span class="line">app.<span class="property">config</span>.<span class="property">globalProperties</span>.<span class="property">$http</span> = <span class="function">() =&gt;</span> &#123; &#125;</span><br><span class="line"></span><br><span class="line">app.<span class="title function_">mount</span>(<span class="string">&#x27;#app&#x27;</span>)</span><br></pre></td></tr></table></figure>

<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line">// Demo.vue</span><br><span class="line"></span><br><span class="line">&lt;template&gt;</span><br><span class="line">  &lt;h1&gt;getCurrentInstance的使用&lt;/h1&gt;</span><br><span class="line">&lt;/template&gt;</span><br><span class="line">&lt;script setup&gt;</span><br><span class="line">import &#123; getCurrentInstance &#125; from &quot;vue&quot;;</span><br><span class="line">const app = getCurrentInstance();</span><br><span class="line">// 全局数据，是不具备响应式的。</span><br><span class="line">const global = app.appContext.config.globalProperties;</span><br><span class="line">console.log(&quot;app&quot;, app);</span><br><span class="line">console.log(&quot;全局数据&quot;, global);</span><br><span class="line">&lt;/script&gt;</span><br></pre></td></tr></table></figure>

<h3 id="总结常用API如下"><a href="#总结常用API如下" class="headerlink" title="总结常用API如下"></a><strong>总结常用API如下</strong></h3><ul>
<li>ref</li>
<li>reactive</li>
<li>watch</li>
<li>computed</li>
<li>watchEffect</li>
<li>toRefs</li>
<li>onMounted</li>
<li>onBeforeUnmount</li>
<li>onActivated</li>
<li>onDeactivated</li>
<li>provide &#x2F; inject 用setup语法糖组合时是有响应式的，如果用选项式写法是没有响应式的（需要使用computed包裹一层）</li>
</ul>
</article><div class="post-copyright"><div class="post-copyright__author"><span class="post-copyright-meta">文章作者: </span><span class="post-copyright-info"><a href="https://hzc-123456.gitee.io/hzcs-blog">韩志成</a></span></div><div class="post-copyright__type"><span class="post-copyright-meta">文章链接: </span><span class="post-copyright-info"><a href="https://hzc-123456.gitee.io/hzcs-blog/2023/05/24/VUE3_Composition_API/">https://hzc-123456.gitee.io/hzcs-blog/2023/05/24/VUE3_Composition_API/</a></span></div><div class="post-copyright__notice"><span class="post-copyright-meta">版权声明: </span><span class="post-copyright-info">本博客所有文章除特别声明外，均采用 <a href="https://creativecommons.org/licenses/by-nc-sa/4.0/" target="_blank">CC BY-NC-SA 4.0</a> 许可协议。转载请注明来自 <a href="https://hzc-123456.gitee.io/hzcs-blog" target="_blank">韩志成的个人空间</a>！</span></div></div><div class="tag_share"><div class="post-meta__tag-list"><a class="post-meta__tags" href="/hzcs-blog/tags/%E6%8A%80%E6%9C%AF/">技术</a></div><div class="post_share"><div class="social-share" data-image="/hzcs-blog/img/avar.jpeg" data-sites="facebook,twitter,wechat,weibo,qq"></div><link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/butterfly-extsrc/sharejs/dist/css/share.min.css" media="print" onload="this.media='all'"><script src="https://cdn.jsdelivr.net/npm/butterfly-extsrc/sharejs/dist/js/social-share.min.js" defer></script></div></div><nav class="pagination-post" id="pagination"><div class="next-post pull-full"><a href="/hzcs-blog/2023/05/19/git_order/" title="常用git操作"><div class="cover" style="background: var(--default-bg-color)"></div><div class="pagination-info"><div class="label">下一篇</div><div class="next_info">常用git操作</div></div></a></div></nav><div class="relatedPosts"><div class="headline"><i class="fas fa-thumbs-up fa-fw"></i><span>相关推荐</span></div><div class="relatedPosts-list"><div><a href="/hzcs-blog/2023/05/19/file/" title="vue下载网络pdf文件到本地"><div class="cover" style="background: var(--default-bg-color)"></div><div class="content is-center"><div class="date"><i class="far fa-calendar-alt fa-fw"></i> 2023-05-19</div><div class="title">vue下载网络pdf文件到本地</div></div></a></div><div><a href="/hzcs-blog/2023/05/19/git_order/" title="常用git操作"><div class="cover" style="background: var(--default-bg-color)"></div><div class="content is-center"><div class="date"><i class="far fa-calendar-alt fa-fw"></i> 2023-05-19</div><div class="title">常用git操作</div></div></a></div></div></div></div><div class="aside-content" id="aside-content"><div class="card-widget card-info"><div class="is-center"><div class="avatar-img"><img src="/hzcs-blog/img/avar.jpeg" onerror="this.onerror=null;this.src='/hzcs-blog/img/friend_404.gif'" alt="avatar"/></div><div class="author-info__name">韩志成</div><div class="author-info__description"></div></div><div class="card-info-data site-data is-center"><a href="/hzcs-blog/archives/"><div class="headline">文章</div><div class="length-num">4</div></a><a href="/hzcs-blog/tags/"><div class="headline">标签</div><div class="length-num">2</div></a><a href="/hzcs-blog/categories/"><div class="headline">分类</div><div class="length-num">4</div></a></div><a id="card-info-btn" target="_blank" rel="noopener" href="https://github.com/xxxxxx"><i class="fab fa-github"></i><span>Follow Me</span></a></div><div class="card-widget card-announcement"><div class="item-headline"><i class="fas fa-bullhorn fa-shake"></i><span>公告</span></div><div class="announcement_content">欢迎来到我的博客</div></div><div class="sticky_layout"><div class="card-widget" id="card-toc"><div class="item-headline"><i class="fas fa-stream"></i><span>目录</span><span class="toc-percentage"></span></div><div class="toc-content"><ol class="toc"><li class="toc-item toc-level-3"><a class="toc-link" href="#ref"><span class="toc-number">1.</span> <span class="toc-text">ref</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#isRef"><span class="toc-number">2.</span> <span class="toc-text">isRef</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#unref"><span class="toc-number">3.</span> <span class="toc-text">unref</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#customRef"><span class="toc-number">4.</span> <span class="toc-text">customRef</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#toRef"><span class="toc-number">5.</span> <span class="toc-text">toRef</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#toRefs"><span class="toc-number">6.</span> <span class="toc-text">toRefs</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#shallowRef"><span class="toc-number">7.</span> <span class="toc-text">shallowRef</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#triggerRef"><span class="toc-number">8.</span> <span class="toc-text">triggerRef</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#reactive"><span class="toc-number">9.</span> <span class="toc-text">reactive</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#readonly"><span class="toc-number">10.</span> <span class="toc-text">readonly</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#isReadonly"><span class="toc-number">11.</span> <span class="toc-text">isReadonly</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#isReactive"><span class="toc-number">12.</span> <span class="toc-text">isReactive</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#isProxy"><span class="toc-number">13.</span> <span class="toc-text">isProxy</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#toRaw"><span class="toc-number">14.</span> <span class="toc-text">toRaw</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#markRaw"><span class="toc-number">15.</span> <span class="toc-text">markRaw</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#shallowReactive"><span class="toc-number">16.</span> <span class="toc-text">shallowReactive</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#shallowReadonly"><span class="toc-number">17.</span> <span class="toc-text">shallowReadonly</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#computed"><span class="toc-number">18.</span> <span class="toc-text">computed</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#watch"><span class="toc-number">19.</span> <span class="toc-text">watch</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#watchEffect"><span class="toc-number">20.</span> <span class="toc-text">watchEffect</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E7%94%9F%E5%91%BD%E5%91%A8%E6%9C%9F%E9%92%A9%E5%AD%90"><span class="toc-number">21.</span> <span class="toc-text">生命周期钩子</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#provide-x2F-inject"><span class="toc-number">22.</span> <span class="toc-text">provide &#x2F; inject</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#getCurrentInstance"><span class="toc-number">23.</span> <span class="toc-text">getCurrentInstance</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E6%80%BB%E7%BB%93%E5%B8%B8%E7%94%A8API%E5%A6%82%E4%B8%8B"><span class="toc-number">24.</span> <span class="toc-text">总结常用API如下</span></a></li></ol></div></div><div class="card-widget card-recent-post"><div class="item-headline"><i class="fas fa-history"></i><span>最新文章</span></div><div class="aside-list"><div class="aside-list-item no-cover"><div class="content"><a class="title" href="/hzcs-blog/2023/05/24/VUE3_Composition_API/" title="Vue3 之 Composition API">Vue3 之 Composition API</a><time datetime="2023-05-24T02:18:00.000Z" title="发表于 2023-05-24 10:18:00">2023-05-24</time></div></div><div class="aside-list-item no-cover"><div class="content"><a class="title" href="/hzcs-blog/2023/05/19/git_order/" title="常用git操作">常用git操作</a><time datetime="2023-05-19T08:27:19.000Z" title="发表于 2023-05-19 16:27:19">2023-05-19</time></div></div><div class="aside-list-item no-cover"><div class="content"><a class="title" href="/hzcs-blog/2023/05/19/file/" title="vue下载网络pdf文件到本地">vue下载网络pdf文件到本地</a><time datetime="2023-05-19T05:58:21.000Z" title="发表于 2023-05-19 13:58:21">2023-05-19</time></div></div><div class="aside-list-item no-cover"><div class="content"><a class="title" href="/hzcs-blog/2023/05/19/hello-world/" title="第一次发布">第一次发布</a><time datetime="2023-05-19T05:38:21.000Z" title="发表于 2023-05-19 13:38:21">2023-05-19</time></div></div></div></div></div></div></main><footer id="footer"><div id="footer-wrap"><div class="copyright">&copy;2020 - 2023 By 韩志成</div><div class="framework-info"><span>框架 </span><a target="_blank" rel="noopener" href="https://hexo.io">Hexo</a><span class="footer-separator">|</span><span>主题 </span><a target="_blank" rel="noopener" href="https://github.com/jerryc127/hexo-theme-butterfly">Butterfly</a></div></div></footer></div><div id="rightside"><div id="rightside-config-hide"><button id="readmode" type="button" title="阅读模式"><i class="fas fa-book-open"></i></button><button id="darkmode" type="button" title="浅色和深色模式转换"><i class="fas fa-adjust"></i></button><button id="hide-aside-btn" type="button" title="单栏和双栏切换"><i class="fas fa-arrows-alt-h"></i></button></div><div id="rightside-config-show"><button id="rightside_config" type="button" title="设置"><i class="fas fa-cog fa-spin"></i></button><button class="close" id="mobile-toc-button" type="button" title="目录"><i class="fas fa-list-ul"></i></button><button id="go-up" type="button" title="回到顶部"><span class="scroll-percent"></span><i class="fas fa-arrow-up"></i></button></div></div><div><script src="/hzcs-blog/js/utils.js"></script><script src="/hzcs-blog/js/main.js"></script><script src="https://cdn.jsdelivr.net/npm/@fancyapps/ui/dist/fancybox/fancybox.umd.min.js"></script><div class="js-pjax"></div><script async data-pjax src="//busuanzi.ibruce.info/busuanzi/2.3/busuanzi.pure.mini.js"></script></div></body></html>